package com.cn.JUC.utils.case12;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Title CompletionService 快速实现 Forking 集群模式
 * @Description 为了保证服务高可用，启动3个任务分别调用3个地图服务，只要有一个服务响应，即可返回结果，取消其它任务。
 * @Author CAI ZHAI
 * @Date 2021/9/9 11:27
 **/
public class ForkingClusterImpl{
    private Integer getOneService() throws Exception{
        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(3);
        // 创建CompletionService：内部含队列
        CompletionService<Integer> cs = new ExecutorCompletionService<>(executor);
        // 用于保存Future对象
        List<Future<Integer>> futures = new ArrayList<>(3);
        //提交异步任务，并保存future到futures
        futures.add(
                cs.submit(()-> geocoderByS1()));
        futures.add(
                cs.submit(()->geocoderByS2()));
        futures.add(
                cs.submit(()->geocoderByS3()));
        // 获取最快返回的任务执行结果
        Integer r = 0;
        try {
            // 只要有一个成功返回，则break
            for (int i = 0; i < 3; ++i) {
                r = cs.take().get();
                //简单地通过判空来检查是否成功返回
                if (r != null) {
                    break;
                }
            }
        } finally {
            //取消所有任务
            for(Future<Integer> f : futures)
                f.cancel(true);
        }
        // 返回结果
        return r;
    }
    
    
    //访问地图1服务
    private Integer geocoderByS1(){
        return null;
    }
    //访问地图2服务
    private Integer geocoderByS2(){
        return null;
    }
    //访问地图3服务
    private Integer geocoderByS3(){
        return null;
    }
}
